package com.reflect;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

public class ReflectUtil {
	
	public static void main(String[] args) throws IOException {
		File file = new File(ReflectUtil.class.getResource("listresource.json").getPath());
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
		
		String line = null;
		StringBuffer str = new StringBuffer();
		
		while((line = reader.readLine()) != null) {
			str.append(line);
		}
		reader.close();
		
	}

	public static <T> T populate(Class<T> cls, Map<String, Object> map)
			throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
			NoSuchMethodException, SecurityException {
		T obj = null;

		// 1、用类反射new出对象
		obj = cls.newInstance();

		// 2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置
		// 2.1遍历出所有该类声明的属性
		Field flds[] = cls.getDeclaredFields();// getDeclaredFields()返回Class中所有的字段，包括私有字段；
		for (Field fld : flds) {
			// 获取该fld对象所代表的属性名
			String fldName = fld.getName();
			// 根据属性名，到map中去读取数据，只有数据非空才需要给该属性设置值
			Object value = map.get(fldName);
			if (value == null) {// 如果map中不存在对应的属性数据，我们在这里给出提示信息
				System.out.println(fldName + "的数据为空");
			} else {
				// 如果map中存在对应的属性数据，则由属性名得出它的setter方法的名字
				String mothodName = "set" + fldName.substring(0, 1).toUpperCase() + fldName.substring(1);

				// 根据方法名和参数的数据类型(其实就是属性的类型)，获得Method对象
				Class<?> paramTypes[] = new Class[1];
				paramTypes[0] = fld.getType();
				if (paramTypes[0] == List.class) {
					// 获取List中的泛型
					ParameterizedType listGenericType = (ParameterizedType) fld.getGenericType();

				}
				Method method = cls.getDeclaredMethod(mothodName, paramTypes);

				// 调用该method对象所代表的方法
				Object args[] = new Object[1];
				args[0] = value;
				method.invoke(obj, args);
			}
		}
		return obj;
	}

}
